#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<errno.h>

int main()
{
    pid_t id = fork();
    if(id < 0)
    {
       printf("fork false\n");
       exit(1);
    }
    else if(id == 0)
    {
        printf("I am a child process! PID : %d\n",getpid());
        sleep(10);
        exit(1);
    }
    else 
    {
        // 基于非阻塞的轮询等待方案
        int status = 0;
        while(1)
        {
            pid_t ret = waitpid(-1,&status,WNOHANG);
            if(ret == 0)
            {
                printf("子进程还没有退出！父进程可以做其它事情！\n");
                sleep(1);
            }
            else if(ret == id&&WIFEXITED(status))
            {
                printf("wait child process success,exit code : %d,exit signal : %d\n",status&0x7F,(status>>8)&0xFF);
                break;
            }
            else 
            {
                printf("wait child failed,return.exit code : %d\n",status&0x7F);
                return 1;
            }
        }
    }
    return 0;
}


//int main()
//{
//    pid_t id = fork();
//    if(id < 0)
//    {
//        perror("fork false");
//        exit(1);
//    }
//    if(id == 0)
//    {
//        printf("I am a child process,pid : %d\n",getpid());
//        sleep(10);
//        exit(17);
//    }
//    else 
//    {
//        int status = 0;
//        int ret = wait(&status);
//        if(ret>0&&(status&0x7F)==0) // 进程正常退出
//        {
//            printf("child process exit code : %d\n",(status>>8)&0xFF);
//        }
//        else if(ret > 0) //进程异常
//        {
//            printf("signal code : %d\n",status&0x7F);
//        }
//    }
//    return 0;
//}


//int main()
//{
//    pid_t pidArray[10]; // 创建10个进程并储存它们的PID
//    for(int i=0;i<10;++i)
//    {
//        pid_t id = fork();
//        if(id == 0)
//        {
//            printf("child process %d created sucessfully! PID : %d\n",i,getpid());
//            sleep(1);
//            exit(i); // 子进程的退出码设置为该子进程PID在数组中的下标
//        }
//        pidArray[i] = id;
//    }
//    for(int i=0;i<10;++i)
//    {
//        int status = 0;
//        pid_t ret = waitpid(pidArray[i],&status,0);
//        if(ret >= 0)
//        {
//            printf("wait child success!PID : %d\n",pidArray[i]);
//            if(WIFEXITED(status))
//                printf("exit code:%d\n",WEXITSTATUS(status));
//            else 
//                printf("killed by signal %d\n",status&0x7F);
//        }
//    }
//    return 0;
//}


//int main()
//{
//    pid_t id = fork();
//    if(id < 0)
//    {
//        fprintf(stderr,"Fork failed !\n");
//        exit(-1);
//    }
//    else if(id == 0)
//    {
//        int count = 2;
//        while(count)
//        {
//            printf("I am a child process！PID:%d --- %d\n",getpid(),count--);
//            sleep(1);
//        }
//        printf("Done from child process!\n");
//        exit(15); // 使用特殊退出码，观察父进程接收到的信息
//    }
//    else 
//    {
//        int status = 0;
//        printf("I am a parent process.Prepare to wait for the child process!PID:%d\n",getpid());
//        pid_t ret = waitpid(id,&status,0);
//        if(ret > 0)
//        {
//            if(WIFEXITED(status))
//            {
//                printf("Child process exit normally,exit code : %d\n",WEXITSTATUS(status));
//            }
//        }
//    }
//    return 0;
//}


//int main()
//{
//    pid_t id = fork();
//    if(id == 0)
//    {
//        // 让子进程打印3次之后退出
//        int count = 3;
//        while(count)
//        {
//            printf("I am a child process! PID : %d --- %d\n",getpid(),count--);
//            sleep(1);
//        }
//        exit(0);
//    }
//
//    int status = 0;
//    sleep(2);
//    printf("I am a parent process,Prepare to wait for the child process. PID : %d\n",getpid());
//    pid_t ret = wait(&status);
//    if(ret > 0)
//    {
//        printf("wait child process sucess!\n");
//        if(WIFEXITED(status))
//        {
//            printf("exit code : %d\n",WEXITSTATUS(status));
//        }
//    }
//    sleep(3);
//    return 0;
//}


//int main()
//{
//    printf("Test exit !");
//    _exit(1);
//    return 0;
//}


//int main()
//{
//    printf("%d:%s\n",127,strerror(127));
//    return 0;
//}


//int main()
//{
//    printf("Test the process exit code!\n");
//    return 0;
//}
